home *** CD-ROM | disk | FTP | other *** search
/ Your Choice 3 / Your Choice Software Collection 3.iso / dos / secdr13d / setenv.asm < prev    next >
Assembly Source File  |  1994-03-02  |  8KB  |  390 lines

  1.     TITLE    setenv - 12.29.93  Large Model
  2.     .MODEL large
  3. setenv_TEXT   SEGMENT WORD PUBLIC 'CODE'
  4.     ASSUME    CS:setenv_TEXT,DS:setenv_TEXT
  5. ;
  6. ;setenv(char * varname,char * strint)
  7. ;
  8. command db    356 dup (?)
  9. set    db    "set "
  10. CR    equ    0dh
  11. EnvPtr    EQU    2CH    ; Offset in PSP
  12. ComInt    EQU    2EH    ; entry point into first Command.Com
  13.             ; through interpreter
  14.  
  15. SegPtr    EQU    ComInt*4 + 2
  16. sssav    dw    0
  17. spsav    dw    0
  18.  
  19. s_path        dw    05h        ; Size of Path.
  20. d_path        db    "PATH="
  21. s_comspec    dw    08h        ; Size of Comspec=.
  22. d_comspec    db    "COMSPEC="
  23. s_prompt    dw    07h        ; Size of Prompt=.
  24. d_prompt    db    "PROMPT="
  25. s_setenv    dw    07h        ; Size of Setenv=.
  26. d_setenv    db    "SETENV="
  27. s_config    dw    07h        ; Size of Config=.
  28. d_config    db    "CONFIG="
  29. equals        equ    $-1
  30.  
  31. szdat    dw    0    ;Size of environment data.
  32. szvar    dw    0    ;Environment variable size.
  33.  
  34. zero    dw    0    ;constant
  35.  
  36. exit_code    db    00h        ; Normal return
  37. setok        db    00h        ; set NZ on some OK set 1.3b
  38.  
  39. envseg dw      0       ;Environment segment address.
  40. envsz    dw    0    ;Environment size in bytes.
  41.  
  42. get4d_err    db    "Error - can't find/recognize environment space.$"
  43.  
  44. msg00        db    "$"
  45. msg01        db    "$"
  46. msg02        db    "environment variable erased$"
  47. msg03        db    "environment variable created$"
  48. msg04        db    "$"
  49. msg05        db    "$"
  50. msg06        db    "$"
  51. msg07        db    "$"
  52. msg08        db    "$"
  53. msg09        db    "$"
  54. msg10        db    "environment space full$"
  55. msgtab        dw    msg00
  56.         dw    msg01
  57.         dw    msg02
  58.         dw    msg03
  59.         dw    msg04
  60.         dw    msg05
  61.         dw    msg06
  62.         dw    msg07
  63.         dw    msg08
  64.         dw    msg09
  65.         dw    msg10
  66.  
  67.     public    _setenv
  68. _setenv proc far
  69.     push    bp
  70.     mov    bp,sp
  71.     push    si
  72.     push    di
  73.     push    es
  74.     push    ds
  75.  
  76.     push    cs
  77.     pop    ds
  78.  
  79.     mov    setok,0
  80.     les    di,ss:[bp+6]    ;char * varname
  81.     mov    bx,di
  82.     mov    cx,255
  83.     mov    al,0
  84.     cld
  85.     repne scasb
  86.     sub    di,bx
  87.     dec    di
  88.     mov    szvar,di    ;size of env var
  89.     les    di,ss:[bp+10]     ;char * string
  90.     mov    bx,di
  91.     mov    cx,255
  92.     mov    al,0
  93.     cld
  94.     repne scasb
  95.     sub    di,bx
  96.     dec    di
  97.     mov    szdat,di    ;size of data var
  98.  
  99.     xor   si,si        ;Point to segment 0
  100.     mov   es,si
  101.     mov   si, word ptr es:[SegPtr]
  102.     mov   ax,si
  103.     dec   ax
  104.     mov   es,ax
  105.  
  106.  
  107. get4d:
  108. ;    find memory descriptor + PSP
  109.     cmp byte ptr es:0,4dh
  110.     jnz inc_seg
  111.     cmp word ptr es:10h,20cdh
  112.     jz  got4d
  113.  
  114. inc_seg:
  115.     mov ax, es        ; Increment
  116.     inc ax            ;   to the next
  117.     mov es, ax        ;      segment boundary.
  118.  
  119. ;    limit search
  120.     mov bx,cs
  121.     cmp ax, bx        ; Have we gone passed current PSP?
  122.     jbe get4d        ; No. Continue.
  123.     push cs
  124.     pop  ds
  125.     cmp  envseg,0
  126.     jnz  nor_ts
  127.     mov  si,offset get4d_err
  128.     jmp  exitmsg
  129. nor_ts:
  130.     jmp  nor_term         ; Exit.
  131.  
  132.  
  133. got4d:
  134.     mov ax,es:EnvPtr+10h    ; Offset in PSP - Environment
  135.     or ax,ax
  136.     jz inc_seg
  137.     push es
  138.     dec ax
  139.     mov es,ax
  140.     cmp byte ptr es:0,4dh
  141.     jnz nxt_env
  142.     mov ah, 00h
  143.     mov al, es:3        ;Get the number of segments.
  144.     mov bx, 10h
  145.     mul bx            ;Get the number of bytes.
  146.     mov cs:envsz, ax    ;Save it.
  147.  
  148.     mov ax, es        ;Increment
  149.     inc ax            ;  to the environment
  150.     mov es, ax        ;     segment boundary.
  151.  
  152. ;    Just a double check for environment space.
  153.  
  154.     xor di,di
  155.     mov si, offset d_path    ; Check
  156.     mov cx, s_path        ;   for
  157.     rep cmpsb        ;     PATH=.
  158.     jz got_env
  159.  
  160.     xor di,di
  161.     mov si, offset d_prompt ; Check
  162.     mov cx, s_prompt    ;   for
  163.     rep cmpsb        ;     PROMPT=.
  164.     jz got_env
  165.  
  166.     xor di,di
  167.     mov si, offset d_comspec ;Check
  168.     mov cx, s_comspec    ;    for
  169.     rep cmpsb        ;      COMSPEC=.
  170.     jz got_env
  171.  
  172.     xor di,di
  173.     mov si, offset d_setenv ; Check
  174.     mov cx, s_setenv    ;   for
  175.     rep cmpsb        ;     SETENV=.
  176.     jz got_env
  177.  
  178.     xor di,di
  179.     mov si, offset d_config ; Check
  180.     mov cx, s_config    ;   for
  181.     rep cmpsb        ;     CONFIG=.
  182.     jz got_env
  183.  
  184.     pop es
  185.     jmp inc_seg        ;    to scan some more.
  186.  
  187. got_env:
  188.     mov ax,es        ;don't change same env twice
  189.     cmp cs:envseg,ax       ; may be pointed to by >1 PSP
  190.     je  nxt_env
  191.     mov cs:envseg,es
  192.     call set_env
  193. nxt_env:
  194.     pop es
  195.     jmp inc_seg
  196.  
  197. nor_term:
  198.     push cs
  199.     pop  ds
  200.     mov al,0
  201.     cmp setok,0
  202.     jne nort1
  203.     mov al, exit_code
  204.     jmp short nort2
  205. nort1:
  206.     mov exit_code,0
  207. nort2:
  208.     mov ah,0
  209.     add ax,ax        ; index to msg table
  210.     mov si, offset msgtab
  211.     add si,ax
  212.     mov dx,0[si]
  213. exitmsg:
  214.     mov ah, 09h        ; display exit msg
  215.     int 21h
  216.     mov al, exit_code    ; Set termination code.
  217.     cbw
  218. comrtn:
  219.     pop    ds
  220.     pop    es
  221.     pop    di
  222.     pop    si
  223.     pop    bp
  224.     ret
  225. _setenv endp
  226.  
  227. set_env proc  near
  228.     mov ax, es        ; environment to
  229.     mov ds, ax        ;   data segment
  230.     xor si,si        ; environment offset
  231.  
  232.     les    di,ss:[bp+6]    ;char * varname
  233.     mov bl, es:[di]     ;1st char of environment variable.
  234.     jmp short zero1
  235.  
  236.  
  237. ;    Scan through environment for the end,
  238. ;    two null bytes.
  239. lp1:
  240.     lodsb            ; Get a byte.
  241.     cmp al, 00h        ; Is it null?
  242.     jz zero1        ; Yes. Got first null.
  243.     jmp lp1         ; Keep looking.
  244.  
  245. ;    Is the variable there?
  246. zero1:
  247.     lodsb            ; Get a byte.
  248.     cmp al, 00h        ; Is it zero?
  249.     jz write_near        ; Yes.    Jump out.
  250.     cmp al, bl        ; Maybe the env. variable?
  251.     jnz lp1         ; No.  Jump out.
  252.  
  253.     dec si            ; We are N+1.
  254.     mov ax, ds        ; Get the data segment
  255.     mov es, ax        ; and put it in extra segment.
  256.     mov di, si        ; This is our destination.
  257.     mov dx, si        ; Save the address of env. var.
  258.  
  259.     lds    si,ss:[bp+6]    ;char * varname
  260.     mov    cx, cs:szvar    ;Length of variable.
  261.     cld
  262.     rep cmpsb        ; Does it exist?
  263.     jz update
  264.  
  265.     mov ax, es        ; Get the extra segment.
  266.     mov ds, ax        ; and put it in data segment.
  267.     mov si, di        ; Setup the source.
  268.     jmp lp1
  269.  
  270. write_near:
  271.     jmp write
  272.  
  273. ;    The environment variable is there.
  274. ;    Now update the environment variable.
  275. update:
  276.  
  277. update0:
  278.     mov ax, es        ; Get the extra segment.
  279.     mov ds, ax        ; and put it in data segment.
  280.     mov di, dx        ; This is our destination.
  281.     mov si, di        ; Setup the source.
  282.  
  283. update1:
  284.     lodsb            ; Skip
  285.     cmp al, 00h        ;   over
  286.     jnz update1        ;     the variable.
  287.  
  288.     lodsb            ; Look ahead to see
  289.     dec si            ;   if the next byte
  290.     cmp al, 00h        ;     is zero if not
  291.     jz update3        ;    compress the data.
  292.  
  293. update2:
  294.     lodsb            ; Compress
  295.     stosb            ;   the data
  296.     cmp al, 00h        ;     for a
  297.     jnz update2        ;    variable.
  298.  
  299.     lodsb            ; Get a byte.
  300.     dec si
  301.     cmp al, 00h        ; Is it zero?
  302.     jnz update2        ; No.  Get next.
  303.  
  304. update3:
  305. update4:
  306.     mov cx, cs:szdat    ; Length of data.
  307.     cmp cx, 00h        ; null data?
  308.     jnz write1        ; No. Jump out.
  309.  
  310.     mov cx, si        ; End of old environment.
  311.     mov dx, di        ; Current position.
  312.     sub cx, dx
  313.     mov al, 00h        ; Zero
  314.     rep stosb        ;  the rest.
  315.     ret
  316.  
  317. ;    The environment variable isn't there.
  318. ;    Now move the data into place.
  319. write:
  320.     mov ax, ds        ; Get the data segment
  321.     mov es, ax        ; and put it in extra segment.
  322.     dec si            ; We are N+1.
  323.     mov di, si        ; This is our destination.
  324.     mov dx, si        ; save for reset
  325.  
  326. write1:
  327.     mov cx, cs:szdat    ; Environment data length
  328.     jcxz write1a        ; delete if none
  329.     jmp short write2    ; No. Jump out.
  330. write1a:
  331.     mov cs:[exit_code], 08h ; Environment variable not found.
  332.     ret
  333.  
  334. write2:
  335.     lds    si,ss:[bp+6]    ;char * varname
  336.     mov    cx, cs:szvar    ;Set the length.
  337.     call    cpytenv     ;copy to env
  338.     push    cs
  339.     pop    ds
  340.     mov    si, offset equals
  341.     mov    cx,1
  342.     call    cpytenv
  343.     lds    si,ss:[bp+10]    ;char * data
  344.     mov    cx, cs:szdat    ;Set the length.
  345.     call    cpytenv
  346.     push    cs
  347.     pop    ds
  348.     mov    si,offset zero
  349.     mov    cx,2
  350.     call    cpytenv
  351.     mov    setok,1
  352.     ret
  353.  
  354. cpytenv label near
  355. write3:
  356.     mov ah, es:[di]     ; Get destination byte.
  357. write4:
  358.     cmp ah, 00h        ; Is it a zero?
  359.     jnz not_zero        ; No.  Jump out.
  360.     lodsb            ; Get byte.
  361.     stosb            ; Save byte.
  362.     loop write3        ; Loop.
  363.     ret
  364.  
  365.  
  366. not_zero:
  367.     mov ax, di        ; Get the current offset.
  368.     mov bx, cs:envsz    ; Get environment size.
  369.     cmp ax, bx        ; Greater than environment size.
  370.     jge reset        ; Yes.    Jump.
  371.     mov ah, 00h        ; Make it zero.
  372.     jmp write4
  373.  
  374. reset:
  375.     mov di, dx
  376.     mov al, 00h        ; Put zero back.
  377.     stosb
  378.     stosb
  379.     mov exit_code, 0Ah    ; Set code for out of env.,
  380.     pop  ax         ; discard inner return
  381.     ret
  382.  
  383.  
  384.  
  385.     public lastloc
  386. lastloc     label    byte        ; End of program.
  387. set_env endp
  388. setenv_TEXT   ENDS
  389.     END
  390.